package com.etown.util;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Properties;
import java.util.Random;

import org.apache.log4j.Logger;

/**
 * 文件读写工具
 * 
 * @author 菜鸟
 */
public class FileUtil {
	private static final Logger log = Logger.getLogger(FileUtil.class);

	/**
	 * 创建目录
	 * 如果路径中的父目录不存在，将会依次创建
	 * @param path
	 * @param overWrite
	 * @return
	 */
	public static File mkDirs(String path){
		return create(path,true,false);
	}
	
	/**
	 * 创建文件
	 * @param path
	 * @param overWrite
	 * @return
	 */
	public static File touch(String path,boolean overWrite){
		return create(path,false,overWrite);
	}
	
	/**
	 * 通用的创建方法
	 * @param path
	 * @param isDir
	 * @param overWrite
	 * @return
	 */
	public static File create(String path,boolean isDir,boolean overWrite){
		File f=new File(path);
		try{
			if(!f.exists()){
				log.debug("文件或目录不存在，开始创建");
				if(isDir){
					f.mkdirs();
				}else{
					f.createNewFile();
				}
			}else{
				if(f.isDirectory()){
					log.debug("目录已存在");
					return f;
				}else if(overWrite){
					if(f.canWrite()){
						log.debug("覆盖文件");
						f.delete();
						f.createNewFile();
					}else{
						log.error("文件无法写入");
					}
				}else{
					log.debug("文件已存在，未覆盖");
				}
			}
		}catch(Exception e){
			log.error("创建文件或目录失败"+e.getMessage());
		}
		return f;
	}
	
	/**
	 * <pre>
	 * 打开一个文件
	 * </pre>
	 */
	public static File open(String path) throws Exception {
		File file = new File(path);
		if (file.exists() && file.isFile()&&file.canRead()) {
			return file;
		} else {
			log.error("无法打开文件：" + path+"，文件不存在或者不可读。");
			return null;
		}
	}
	
	/**
	 * 加载Properties文件
	 * @param path
	 * @return
	 */
	public static Properties loadProperty(String path){
		Properties p = new Properties();
		try{
			File file = FileUtil.open(path);
			FileInputStream fin = new FileInputStream(file);
			p.load(fin);
		}catch(Exception e){
			log.error("加载Properties文件失败"+e.getMessage());
		}
		return p;
	}

	/**
	 * <pre>
	 * 在文件最后添加一行
	 * </pre>
	 */
	public static File append(String path, String content) throws Exception {
		File file = open(path);
		if (file.canWrite()) {
			FileWriter fr = new FileWriter(file, true);
			PrintWriter pr = new PrintWriter(fr);
			pr.println(content);
			pr.close();
		} else {
			log.error("文件" + path + "无法写入。");
		}
		return file;
	}

	/**
	 * <pre>
	 * 以文本方式读出所有内容
	 * </pre>
	 */
	public static String readAll(String path) throws Exception {
		File file = open(path);
		StringBuilder builder = new StringBuilder();
		if (file.canRead()) {
			FileInputStream fs=new FileInputStream(path);
			InputStreamReader ir=new InputStreamReader(fs,"utf-8");
			BufferedReader br = new BufferedReader(ir);
			String line = "";
			while ((line = br.readLine()) != null) {
				builder.append(line);
			}
			br.close();
		} else {
			log.error("无法读取文件" + path + "的内容。");
		}
		return builder.toString();
	}

	/**
	 * <pre>
	 * 以content的内容覆盖当前文件
	 * </pre>
	 */
	public static File overWrite(String path, String content) throws Exception {
		File file = open(path);
		if (file.exists()&&!file.isDirectory()&&file.canWrite()) {
			BufferedWriter output = new BufferedWriter(new FileWriter(file));
			output.write(content);
			output.close();
		} else {
			log.error("文件" + path + "不存在或者无法写入。");
		}
		return file;
	}

	/**
	 * 上传文件
	 * 
	 * @param uploadFileName
	 *          被上传的文件名称
	 * @param savePath
	 *          文件的保存路径
	 * @param uploadFile
	 *          被上传的文件
	 * @return newFileName
	 */
	public static String upload(String uploadFileName, String savePath, File uploadFile) {
		String newFileName = getRandomName(uploadFileName, savePath);
		try {
			FileOutputStream fos = new FileOutputStream(savePath + newFileName);
			FileInputStream fis = new FileInputStream(uploadFile);
			byte[] buffer = new byte[1024];
			int len = 0;
			while ((len = fis.read(buffer)) > 0) {
				fos.write(buffer, 0, len);
			}
		} catch (FileNotFoundException e) {
			EnvInitServlet.etownlogger.error("文件没有找到！",e);
		} catch (IOException e) {
			EnvInitServlet.etownlogger.error("上传文件失败报错！",e);
		}
		return newFileName;
	}
	/**
	 * 获得随机文件名,保证在同一个文件夹下不同名
	 * 
	 * @param fileName
	 * @param dir
	 * @return
	 */
	public static String getRandomName(String fileName, String dir) {
		String[] split = fileName.split("\\.");// 将文件名已.的形式拆分
		String extendFile = "." + split[split.length - 1].toLowerCase(); // 获文件的有效后缀

		Random random = new Random();
		int add = random.nextInt(1000000); // 产生随机数10000以内
		String ret = add + extendFile;
		while (isFileExist(ret, dir)) {
			add = random.nextInt(1000000);
			ret = fileName + add + extendFile;
		}
		return ret;
	}
	/**
	 * 判断文件是否存在
	 * 
	 * @param fileName
	 * @param dir
	 * @return
	 */
	public static boolean isFileExist(String fileName, String dir) {
		File files = new File(dir + fileName);
		return (files.exists()) ? true : false;
	}
	
	public static void main(String[] args) throws Exception {
		// FileUtil.open("c://test.txt");
		// FileUtil.append("c:\\test.txt", "添加一行");
		// FileUtil.overWrite("c:\\test.txt", "开始覆盖啦...");
//		String result = FileUtil.readAll("c:\\test.txt");
//		System.out.println(result);
		//FileUtil.touch("c:\\test.txt", true);
		//FileUtil.overWrite("c:\\test.txt", "这是测试的内容");
		FileUtil.mkDirs("c:\\mydir");
	}
}
